#ifndef PRODUCTLISTMODEL_H
#define PRODUCTLISTMODEL_H

#include <QAbstractListModel>
#include <iapclient.h>

class PurchasableItemBase;
class IAPClient;

class ProductListModel : public QAbstractListModel
{
    Q_OBJECT
    friend class FilterProxyModel;

public:
    Q_PROPERTY(bool isApplicationBusy READ isApplicationBusy NOTIFY applicationBusyChanged)

    explicit ProductListModel(QObject *parent = 0);
    ~ProductListModel();

public: // From QAbstractListModel
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;
    bool setData (const QModelIndex &index,
                    const QVariant &value, int role = Qt::EditRole);

    bool isApplicationBusy() const;

public:
    // for model items to use only
    /*!
      Switches the model to update mode
    */
    void beginModelUpdate();
    /*!
      Commits updates in the model
    */
    void commitModelUpdate();
    /*!
      Getters for In-application API client
     */
    IAPClient &client();
    /*!
      Callback function on Purchase Flow Finished event
     */
    void purchaseFlowFinished(bool statusSuccess);

signals:
    /*!
      The signal supports ProductCatalogModel::isApplicationBusy property notification
    */
    void applicationBusyChanged();

    /*!
      Signals towards Filter and Sorting Proxy model
    */
    void modelUpdated();

    /*!
      signals towards Filter and Sorting Proxy model
    */
    void purchaseCompleted(bool status);

private slots:

    void initIAP();
    void userAndDeviceDataReceived( int requestId, QString status,
                                    IAPClient::UserAndDeviceDataHash userdata );
    void restorableProductsReceived( int requestId, QString status,
                                     IAPClient::ProductDataList items );

private:
    //utility functions
    /*!
      Reads product catalog
    */
    void readDRMCatalog();
    /*!
      Getter to obtain product data by index
    */
    PurchasableItemBase *record(int index) const;
    /*!
      Getter to obtain product data by virtual index
      virtual index supports the model sorting and filtering
      additional info please see in ProductCatalogModel class implementation
      As parameter accepts product virtual index seen by QML
    */
    PurchasableItemBase *record(const QModelIndex &index) const;
    /*!
      Buy product request
      As parameter accepts product virtual index seen by QML
    */
    void buy(const QModelIndex &index);
    /*!
      Restore product request
    */
    void restoreProducts();
    /*!
      Get user info request
    */
    void getUserInfo();

    /*!
      this trigger is to prevent list flickering during first time built
      \returns whether model redrawing is possible on QML side
    */
    bool allowModelUpdateNotifications();

    void resetPurchases();

private:
    // In-Application Purchase API
    IAPClient                       *m_client;

    //for aggregate query to product list getRestorableProducts()
    int                             m_requestId;
    // the model reference counter to support commit group operation
    int                             m_modelCommitRefCounter;

    // enables the whole application busy indicator
    bool                            m_isApplicationBusy;

    // the model data
    QList<PurchasableItemBase*>     m_data;
};

#endif // PRODUCTLISTMODEL_H
